package com.xnew.user.controller;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.xnew.aes.SecurityParameter;
import com.xnew.bean.common.SysUserInfo;
import com.xnew.constant.Constant;
import com.xnew.entity.ssoApi.LoginDo;
import com.xnew.entity.ssoApi.TokenDo;
import com.xnew.ssoApi.service.SsoApiService;
import com.xnew.utils.ImageVerificationUtil;
import com.xnew.utils.RedisUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.xnew.user.service.LoginService;
import com.xnew.utils.ResponseUtil;
@Controller
@RequestMapping("/shiro-api")
public class LoginController {
	
	@Autowired
	private LoginService loginService;
	@Resource
	private SsoApiService ssoApiService;

    /**
     * 跳转到/login.html页面
     * @return
     */
    @RequestMapping("/index")
    public String index() {
        return "/login";
    }

    /**
     *  登陆认证，检查账号密码是否正确。成功则跳转到index.html，错误则跳转到对应的error.html
     * @return
     */
    @ResponseBody
    @RequestMapping("/userLogin")
    @SecurityParameter
    public String userLogin(HttpServletRequest request){
    	long startTime = System.currentTimeMillis();
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(request.getParameter("userName"),request.getParameter("password"));
        Subject subject=SecurityUtils.getSubject();
        Map<String, Object> map = new HashMap<String, Object>();
        try {
        	subject.login(usernamePasswordToken);
  			map = loginService.login("",request.getParameter("userName"), request, "app");
  			map.put("loadTime", String.valueOf(System.currentTimeMillis()-startTime));
  			return ResponseUtil.responseMsg(map);
        }catch (IncorrectCredentialsException ice){
        	map.put("error","password error");
        }catch (UnknownAccountException uae) {
        	map.put("error","userName error");
        }catch (ExcessiveAttemptsException eae) {
        	map.put("error","time error");
        }catch (Exception e) {
        	e.printStackTrace();
        	map.put("error","resource error");
		}
        map.put("loadTime", String.valueOf(System.currentTimeMillis()-startTime));
        return ResponseUtil.responseMsg(map);
    }
    
    /**
     *  登陆认证，检查账号密码是否正确。成功则跳转到index.html，错误则跳转到对应的error.html
     * @return
     */
    @ResponseBody
    @RequestMapping("/login")
//    @SecurityParameter
    public String login(@RequestBody JSONObject json, HttpServletRequest request){
    	String requestCode = json.getString("requestCode");
    	String code = json.getString("code");
//    	if(null == code || "".equals(code) || !code.equals(RedisUtil.get(requestCode))) {
//    		return ResponseUtil.responseMsg("1111", "验证码错误");
//    	}
    	long startTime = System.currentTimeMillis();
        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(json.getString("userName"),json.getString("password"));
        Subject subject=SecurityUtils.getSubject();
        Map<String, Object> map = new HashMap<String, Object>();
        try {
        	subject.login(usernamePasswordToken);
  			map = loginService.login("",json.getString("userName"), request, "pc");
  			map.put("loadTime", String.valueOf(System.currentTimeMillis()-startTime));
  			return ResponseUtil.responseMsg(map);
        }catch (IncorrectCredentialsException ice){
        	map.put("error","password error");
        }catch (UnknownAccountException uae) {
        	map.put("error","userName error");
        }catch (ExcessiveAttemptsException eae) {
        	map.put("error","time error");
        }catch (Exception e) {
        	e.printStackTrace();
        	map.put("error","resource error");
		}
        map.put("loadTime", String.valueOf(System.currentTimeMillis()-startTime));
        return ResponseUtil.responseMsg(map);
    }
    
    /**
	 	* 退出
	 * */
	@RequestMapping("/loginout")
	@ResponseBody
	@SecurityParameter
	public String loginout(@RequestBody JSONObject json, HttpServletRequest request) {
		try {
			SysUserInfo user = (SysUserInfo) request.getSession().getAttribute(Constant.LOGIN_USER);
			String token = RedisUtil.get("USER_ID:"+user.getUserInfoNo());
			RedisUtil.del(token);
			RedisUtil.del("USER_ID:"+user.getUserInfoNo());
	    	return ResponseUtil.responseMsg("0001","退出成功!");
		}catch(Exception e) {
			e.printStackTrace();
			return ResponseUtil.responseMsg("9999","系统异常!");
		}
	}
	
	/**
    1.生成验证码
    2.把验证码上的文本存在session中
    3.把验证码图片发送给客户端
    */
	@RequestMapping("/getVerifiCode")
	@ResponseBody
	public void getVerifiCode(HttpServletRequest request,HttpServletResponse response){
		try {
			System.out.println("请求编码："+request.getParameter("requestCode"));
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("image/jpeg");
			// 生成随机字串
			String verifyCode = ImageVerificationUtil.generateVerifyCode(4);
			RedisUtil.set(request.getParameter("requestCode"), verifyCode);
			RedisUtil.expire(request.getParameter("requestCode"), 60);
			// 生成图片
			int w = 100, h = 30;
			OutputStream out = response.getOutputStream();
			ImageVerificationUtil.outputImage(w, h, out, verifyCode);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 *  登陆认证，检查账号密码是否正确。成功则跳转到index.html，错误则跳转到对应的error.html
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/oaPcLogin")
	@SecurityParameter
	public String oaPcLogin(@RequestBody JSONObject json, HttpServletRequest request){
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			String portalUser = json.getString("portalUser");//26F793E1FA48415B382BEB91A294D3F3
			String serviceURL = URLEncoder.encode(Constant.oaLoginUrl, "utf-8");

			// 从idpServer获得ticket
			String url = Constant.oaLoginService + "?service=" + serviceURL + "&portalUser=" + portalUser;
			System.out.println(url);
			String res = retrieve(url);
			System.out.println("=============================ticket res=" + res);

			org.json.JSONObject rerurnJson = new org.json.JSONObject(res);
			boolean success = rerurnJson.getBoolean("success");

			if (success) {
				String ticket = rerurnJson.getString("ticket");

				// 从idpServer获得用户id
				url = Constant.oaLoginService + "?service=" + serviceURL + "&ticket=" + ticket;
				res = retrieve(url);
				System.out.println("=============================uid res=" + res);

				rerurnJson = new org.json.JSONObject(res);
				success = rerurnJson.getBoolean("success");
				if (success) {
					String uid = rerurnJson.getString("uid");
					System.out.println("=============================get userId=" + uid);
					map = loginService.loginByUserId(uid, request, "pc");
					return ResponseUtil.responseMsg(map);
				}
			} else {
				System.out.println("=============================get userId fail");
				map.put("error","resource error");
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			map.put("error","resource error");
		}
		return ResponseUtil.responseMsg(map);
	}

	/**
	 * 发起http请求并处理返回信息
	 * @author yangcd
	 * @param url 请求地址
	 * @return 返回信息
	 * */
	public static String retrieve(String url) throws IOException {
		String value = null;
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader read = null;
		try {
			HttpURLConnection connect = (HttpURLConnection) ((new URL(url)).openConnection());
			connect.setRequestMethod("GET");
			connect.setReadTimeout(10 * 1000);
			connect.setDoOutput(true);

			in = connect.getInputStream();
			isr = new InputStreamReader(in);
			read = new BufferedReader(isr);

			StringBuffer buf = new StringBuffer();
			String valueLine = null;
			while ((valueLine = read.readLine()) != null) {
				buf.append(valueLine);
			}
			value = buf.toString();
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (read != null) {
				read.close();
			}
			if (isr != null) {
				isr.close();
			}
			if (in != null) {
				in.close();
			}
		}

		return value;
	}

	/**
	 *  登陆认证，检查账号密码是否正确。成功则跳转到index.html，错误则跳转到对应的error.html
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/ssoLogin")
	public String ssoLogin(@RequestBody JSONObject json, HttpServletRequest request){
		String openId = "";
		String accessToken = "";
		String token = "";
		String userJson = "";
		String code = json.getString("code");
		String loginType = json.getString("loginType");
		long startTime = System.currentTimeMillis();
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			if(code!=null && !code.trim().equals("")){
				token = RedisUtil.get("SSO_CODE:" + code);
				if(token!=null && !token.trim().equals("")){
					System.out.println("====通过code获取门户Token====");//通过code获取门户Token
					TokenDo tokenObj = ssoApiService.getToken(code);
					if(tokenObj==null) {
						map.put("error","平台token为空！请重新从门户登录！");
						return ResponseUtil.responseMsg(map);
					}
					accessToken = tokenObj.getAccess_token();
					System.out.println("accessToken : " + accessToken);
					if(accessToken==null) {
						map.put("error","平台access_token 为空！请重新从门户登录！");
						return ResponseUtil.responseMsg(map);
					}
					System.out.println("====通过门户Token获取用户信息====");//通过门户Token获取用户信息
					LoginDo loginObj = ssoApiService.getUserInfo(accessToken);
					if(loginObj==null) {
						map.put("error","平台用户信息为空！请于管理员联系！");
						return ResponseUtil.responseMsg(map);
					}
					openId = loginObj.getId();
					System.out.println("openId : " + openId);
					if(openId==null) {
						map.put("error","平台id为空！请于管理员联系！");
						return ResponseUtil.responseMsg(map);
					}
					map = loginService.ssoLogin(code,accessToken,openId,loginType,request);
				}else{
					userJson = RedisUtil.get(token);
					map.put("status", "SUCCESS");
					map.put("message", "登陆成功");
					map.put("token", token);
					map.put("sucess", true);
				}
			}
			map.put("loadTime", String.valueOf(System.currentTimeMillis()-startTime));
			return ResponseUtil.responseMsg(map);
		}catch (IncorrectCredentialsException ice){
			map.put("error","password error");
		}catch (UnknownAccountException uae) {
			map.put("error","userName error");
		}catch (ExcessiveAttemptsException eae) {
			map.put("error","time error");
		}catch (Exception e) {
			e.printStackTrace();
			map.put("error","resource error");
		}
		map.put("loadTime", String.valueOf(System.currentTimeMillis()-startTime));
		return ResponseUtil.responseMsg(map);
	}

    /**
     * 退出
     * */
    @RequestMapping("/ssoLoginout")
    @ResponseBody
    @SecurityParameter
    public String ssoLoginout(String code, HttpServletRequest request) {
        try {
			if(code!=null && !code.trim().equals("")){
				System.out.println(code);
				String token = RedisUtil.get("SSO_CODE:" + code);
				RedisUtil.del(token);
				RedisUtil.del("SSO_CODE:" + code);
			}
            return ResponseUtil.responseMsg("200","操作成功");
        }catch(Exception e) {
            e.printStackTrace();
            return ResponseUtil.responseMsg("9999","系统异常!");
        }
    }
	public static void main(String[] args) {
    	
	}
    
}
